home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
050
/
madtrb13.arc
/
WINDOWZ.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1985-05-19
|
7KB
|
218 lines
{ A set of routines for text window manipulation
By Bela Lubkin
Borland International Technical Support
1/10/85
(For PC-DOS Turbo Pascal version 2 or greater)
Notes: These routines cause extreme blinking on the color monitor. If anyone
modifies them to decrease this blinking, please upload your modified
routines to the Borland SIG on CompuServe - GO BOR
REMEMBER to dispose of your windows, or you will quickly run out of
heap space. Procedure DRestoreWindow restores a window to the screen
and then disposes of the window; procedure DisposeWindow disposes of
a window. DO NOT USE Turbo's built in Dispose procedure on a window;
windows are allocated with GetMem and must be disposed with FreeMem. }
Type
XTCoord=1..80; { X Text coordinate }
YTCoord=1..25; { Y Text coordinate }
XTCoord0=0..80; { X Text coordinate + 0 for nothing }
YTCoord0=0..25; { Y Text coordinate + 0 for nothing }
WindowRec=Record
XSize: XTCoord;
YSize: YTCoord;
XPosn: XTCoord;
YPosn: YTCoord;
Contents: Array [0..1999] Of Integer;
End;
WindowPtr=^WindowRec;
Var
ScreenBase: Integer; { Segment address of the screen: $B000 for monochrome,
$B800 for color }
WindowXLo: XTCoord;
WindowYLo: YTCoord;
WindowXHi: XTCoord;
WindowYHi: YTCoord;
Procedure TurboWindow(XL: XTCoord; YL: YTCoord; XH: XTCoord; YH: YTCoord);
{ This procedure provides an entry to Turbo's built in Window procedure }
Begin
Window(XL,YL,XH,YH);
End;
Procedure Window(XL: XTCoord; YL: YTCoord; XH: XTCoord; YH: YTCoord);
{ This procedure replaces Turbo's built in Window procedure. It calls the
original Window procedure, and also keeps track of the window boundaries. }
Begin
TurboWindow(XL,YL,XH,YH);
WindowXLo:=XL;
WindowYLo:=YL;
WindowXHi:=XH;
WindowYHi:=YH;
End;
Function SaveWindow(XLow: XTCoord; YLow: YTCoord;
XHigh: XTCoord; YHigh:YTCoord): WindowPtr;
{ Allocate a WindowRec of the precise size needed to save the window, then
fill it with the text that is in the window XLow..XHigh, YLow..YHigh.
Return a pointer to this WindowRec. }
Var
SW: WindowPtr;
I: Integer;
XS: XTCoord;
YS: YTCoord;
Begin
XS:=XHigh-XLow+1;
YS:=YHigh-YLow+1;
GetMem(SW,2*XS*YS + 4);
{ Allocate 2 bytes for each screen position, + 4 for size and position }
With SW^ Do
Begin
XSize:=XS;
YSize:=YS;
XPosn:=XLow;
YPosn:=YLow;
For I:=0 To YSize-1 Do
Move(Mem[ScreenBase:((YPosn+I-1)*80+XPosn-1) Shl 1],
Contents[I*XSize],XSize Shl 1);
{ For each line of the window,
Move XSize*2 bytes (1 for char, 1 for attribute) into the Contents
array. Leave no holes in the array. }
End;
SaveWindow:=SW;
End;
Function SaveCurrentWindow: WindowPtr;
Begin
SaveCurrentWindow:=SaveWindow(WindowXLo,WindowYLo,WindowXHi,WindowYHi);
End;
Procedure RestoreWindow(WP: WindowPtr; XPos: XTCoord0; YPos: YTCoord0);
{ Given a pointer to a WindowRec, restore the contents of the window. If
XPos or YPos is 0, use the XPosn or YPosn that the window was originally
saved with. If either is nonzero, use it. Thus a window can be restored
exactly with RestoreWindow(wp,0,0); or its upper left corner can be
placed at (2,3) with RestoreWindow(wp,2,3); }
Var
I: Integer;
Begin
With WP^ Do
Begin
If XPos=0 Then XPos:=XPosn;
If YPos=0 Then YPos:=YPosn;
For I:=0 To YSize-1 Do
Move(Contents[I*XSize],
Mem[ScreenBase:2*((YPos+I-1)*80+XPos-1)],XSize*2);
{ For each line of the window,
Move XSize*2 bytes (1 for char, 1 for attribute) from the Contents
array onto the screen. }
End;
End;
Procedure DisposeWindow(Var WP: WindowPtr);
{ Dispose of a WindowPtr. The built in procedure Dispose cannot be used,
because it will deallocate SizeOf(WindowRec) bytes, even though less may
have been allocated. }
Begin
With WP^ Do FreeMem(WP,2*XSize*YSize+4);
WP:=Nil;
End;
Procedure DRestoreWindow(Var WP: WindowPtr; XPos: XTCoord0; YPos: YTCoord0);
{ Restore the contents of a window, then dispose of the saved image }
Begin
RestoreWindow(WP, XPos, YPos);
DisposeWindow(WP);
End;
Procedure DRestoreCurrentWindow(Var WP: WindowPtr;
XPos: XTCoord0; YPos: YTCoord0);
{ Restore the contents of a window, set the current window to fit the restored
window, and dispose of the saved image. A similar procedure
RestoreCurrentWindow could be written by changing DRestoreWindow to
RestoreWindow in the last line of the procedure, but I have assumed that
when you select a window area, you are going to modify it, and not want the
old image }
Begin
With WP^ Do
Begin
If XPos=0 Then XPos:=XPosn;
If YPos=0 Then YPos:=YPosn;
Window(XPos,YPos,XPos+XSize-1,YPos+YSize-1);
End;
DRestoreWindow(WP, XPos, YPos);
End;
Procedure DetermineDisplay;
{ Set ScreenBase to $B000 or $B800, depending on which display is in use.
A side effect is that the cursor is left at (1,1) on the screen. }
Var
M,C: Integer;
T: Byte;
Begin
M:=MemW[$B000:0];
C:=MemW[$B800:0];
T:=64;
If (Hi(M)=T) Or (Hi(C)=T) Then T:=65;
If (Hi(M)=T) Or (Hi(C)=T) Then T:=66;
GotoXY(1,1);
Write(Chr(T));
GotoXY(1,1);
If Mem[$B000:0]=T Then ScreenBase:=$B000
Else ScreenBase:=$B800;
MemW[$B000:0]:=M;
MemW[$B800:0]:=C;
End;
{ Example program -- remove next line to enable }
Var
X,Y: Byte;
W,W2: WindowPtr;
Ch: Char;
Begin
DetermineDisplay; { Set ScreenBase according to the display in use }
For Y:=1 To 1999 Do
Write(Chr(Random(95)+32)); { Fill the screen with junk }
W:=SaveWindow(1,1,80,25); { Save the whole screen }
Read(Kbd,Ch);
ClrScr; { Clear it }
Read(Kbd,Ch);
DRestoreWindow(W,0,0); { Restore it }
Read(Kbd,Ch);
Window(5,4,53,23);
W:=SaveCurrentWindow; { Save a medium sized window }
ClrScr; { Wipe that window }
Read(Kbd,Ch);
RestoreWindow(W,0,0); { And restore it }
Window(1,1,80,25);
Read(Kbd,Ch);
W2:=SaveWindow(2,2,10,10); { Save a small window }
ClrScr;
Read(Kbd,Ch);
For X:=1 To 72 Do { Restore it in a square around the edges of }
RestoreWindow(W2,X,1); { the screen }
For Y:=2 To 17 Do
RestoreWindow(W2,72,Y);
For X:=71 DownTo 1 Do
RestoreWindow(W2,X,17);
For Y:=16 DownTo 1 Do
RestoreWindow(W2,1,Y);
Read(Kbd,Ch);
DisposeWindow(W2);
DRestoreWindow(W,0,0); { Restore the medium sized window saved earlier }
End.
(**)